package com.takeshi.landlords.config;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import io.netty.handler.stream.ChunkedWriteHandler;
import io.netty.handler.timeout.IdleStateHandler;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

/**
 * NettyBooter
 *
 * @author Nanase Takeshi
 * @date 2022/2/16 14:14
 */
@Component
public class NettyBooster implements ApplicationRunner {

    @Override
    public void run(ApplicationArguments args) throws Exception {
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            ServerBootstrap serverBootstrap =
                    new ServerBootstrap()
                            .group(bossGroup, workerGroup)
                            .channel(NioServerSocketChannel.class)
                            .handler(new LoggingHandler(LogLevel.INFO))
                            .childHandler(new ChannelInitializer<SocketChannel>() {
                                @Override
                                protected void initChannel(SocketChannel socketChannel) throws Exception {
                                    socketChannel.pipeline().addLast(
                                            // 解码器
                                            new HttpServerCodec(),
                                            // new ChunkedWriteHandler() 支持异步发送大的码流(大的文件传输),但不占用过多的内存，防止java内存溢出
                                            new ChunkedWriteHandler(),
                                            // new HttpObjectAggregator() http 消息聚合器  512*1024为接收的最大content-length
                                            new HttpObjectAggregator(8192),
                                            // websocket支持,设置路由
                                            new WebSocketServerProtocolHandler("/nio"),
                                            // 心跳检测
                                            new IdleStateHandler(60, 0, 0),
                                            new NettyWebSocketHandler()
                                    );
                                }
                            });
            ChannelFuture channelFuture = serverBootstrap.bind(11000).sync();
            channelFuture.channel().closeFuture().sync();
        } finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }

}
